package wml.switcher.view;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

public class ImageManager {
	private int num;
	private String filePath = "/sdcard/sliande/";
	private BlockingQueue<LoadImageTask> tasks = new LinkedBlockingQueue<LoadImageTask>(
			9);
	private HashSet<Integer> loaded = new HashSet<Integer>();
	private HashMap<Integer, Bitmap> cached = new HashMap<Integer, Bitmap>();
	private HashMap<Integer, Bitmap> cachedSmall = new HashMap<Integer, Bitmap>();
	private String baseUrl;
	private Handler mHandler;

	public ImageManager(Handler mHandler, String baseUrl) throws IOException {
		this.mHandler = mHandler;
		this.baseUrl = baseUrl;
		File dir = new File(this.filePath);
		dir.delete();
		URL url = new URL(baseUrl + "num");
		URLConnection conn = url.openConnection();
		conn.connect();
		String sn = conn.getHeaderField("num");
		this.num = Integer.parseInt(sn.trim());
	}

	public int getNum() {
		return this.num;
	}

	private String getFilePath(int position) {
		if (!this.loaded.contains(position)) {
			LoadImageTask task = new LoadImageTask();
			if (this.tasks.size() == 9) {
				this.tasks.poll().cancel(true);
			}
			Log.d("switcher", "tasks:" + this.tasks.size());
			this.tasks.offer(task);
			task.execute(position);
			return "/sdcard/sliande/icon.png";
		}
		return filePath + "Slide" + position + ".jpg";
	}

	public void releaseCache(int position) {
		for (int del = 0; del < num; del++) {
			if (del >= position - 3 && del <= position + 7)
				continue;
			Bitmap bmp = cached.get(del);
			Bitmap sbmp = cachedSmall.get(del);
			if (bmp != null) {
				cached.remove(del);
				cachedSmall.remove(del);
				bmp.recycle();
				sbmp.recycle();
			}
		}
	}

	public Bitmap getImage(int position, boolean small) {
		Log.d("switcher", small + " getImage:" + position);
		Bitmap bitmap = null;
		try {
			if (small) {
				BitmapFactory.Options options = new BitmapFactory.Options();
				options.inSampleSize = 8;
				bitmap = BitmapFactory.decodeStream(
						new FileInputStream(this.getFilePath(position)), null,
						options);
			} else {
				bitmap = BitmapFactory.decodeStream(new FileInputStream(this
						.getFilePath(position)));
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		return bitmap;
	}

	class LoadImageTask extends AsyncTask<Integer, Void, Void> {
		@Override
		protected Void doInBackground(Integer... params) {
			try {
				URL url = new URL(baseUrl + "Slide" + (params[0] + 1) + ".jpg");
				URLConnection conn = url.openConnection();
				conn.connect();
				InputStream is = conn.getInputStream();
				writeToSdcard("sdcard/sliande/Slide" + params[0] + ".jpg", is);
				is.close();
				loaded.add(params[0]);
				Message msg = new Message();
				msg.what = params[0];
				mHandler.sendMessage(msg);
			} catch (IOException e) {
				e.printStackTrace();
			}
			return null;
		}
	}

	public void writeToSdcard(String fileName, InputStream is) {
		try {
			File file = new File(fileName);
			File parent = file.getParentFile();
			if (!parent.exists()) {
				parent.mkdirs();
			}
			if (!file.exists()) {
				file.createNewFile();
			}
			FileOutputStream fout = new FileOutputStream(fileName);
			byte[] buffer = new byte[8192];
			int length = 0;
			while ((length = is.read(buffer)) > 0) {
				fout.write(buffer, 0, length);
			}
			fout.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
